package com.itheima.appserver.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.config.MyThreadLocal;
import com.itheima.commons.pojo.*;
import com.itheima.commons.vo.NearUserVo;
import com.itheima.commons.vo.PageResult;
import com.itheima.commons.vo.TodayBest;
import com.itheima.commons.vo.UserLocationVo;
import com.itheima.dubbo.interfaces.RecommendUserApi;
import com.itheima.dubbo.interfaces.UserInfoApi;
import com.itheima.dubbo.interfaces.UserLocationApi;
import com.itheima.dubbo.interfaces.VisitorsApi;
import org.bson.types.ObjectId;
import org.elasticsearch.common.geo.GeoPoint;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class TanhuaService {

    @Reference
    private RecommendUserApi recommendUserApi;

    @Reference
    UserInfoApi userInfoApi;

    @Reference
    VisitorsApi visitorsApi;

    @Reference
    UserLocationApi userLocationApi;



    public RecommendUser findRecommendUser() {
        RecommendUser bestInfo = recommendUserApi.findRecommendUserById(MyThreadLocal.getUserId());
        return bestInfo;
    }

    //查询佳人id的UserInfo
    public UserInfo findBestUserInfo(Long bestId) {
        System.out.println(bestId);
        UserInfo bestInfo = userInfoApi.findById(bestId);
        System.out.println(bestInfo);
        return bestInfo;
    }

    public PageResult findRecommendList(Map<String, Object> parms) {
        PageResult allRecommendUsersById = recommendUserApi.findAllRecommendUsersById(MapUtil.getInt(parms, "pagesize", 10), MapUtil.getInt(parms, "page", 1), MyThreadLocal.getUserId());
        List<RecommendUser> allRecommendUsersByIdItems = (List<RecommendUser>) allRecommendUsersById.getItems();
        //allRecommendUsersByIdItems 有可能出现没有推荐朋友的情况

        //从allRecommendUsersByIdItems获取用户id
        List<Long> userIdList = CollUtil.getFieldValues(allRecommendUsersByIdItems, "userId", Long.class);

        //把用户筛选条件传递进来
        UserInfo userInfo = new UserInfo();
        userInfo.setSex(MapUtil.getStr(parms, "gender"));
        userInfo.setCity(MapUtil.getStr(parms, "city"));
        userInfo.setAge(MapUtil.getInt(parms, "age"));

        //key为userId，value为 userInfo
        Map<Long, UserInfo> infoByUserid = userInfoApi.findUserInfoByUserid(userInfo, userIdList);

        if (MapUtil.isEmpty(infoByUserid)) {
            allRecommendUsersById.setItems(Collections.emptyList());
            return allRecommendUsersById;
        }
        List<TodayBest> voList = new ArrayList<>();
        for (RecommendUser allRecommendUsersByIdItem : allRecommendUsersByIdItems) {
            voList.add(TodayBest.init(infoByUserid.get(allRecommendUsersByIdItem.getUserId()), allRecommendUsersByIdItem));
        }


        allRecommendUsersById.setItems(voList);

        return allRecommendUsersById;

    }

    // 个人主页上的个人信息
    public TodayBest queryUserInfo(Long userId) {
        Visitors visitors = new Visitors();
        visitors.setId(new ObjectId());
        visitors.setUserId(userId);
        visitors.setVisitorUserId(MyThreadLocal.getUserId());
        visitors.setFrom("个人主页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setScore(0.0D);
        visitorsApi.sava(visitors);

        UserInfo userInfo = userInfoApi.findById(userId);

        RecommendUser recommendUser = recommendUserApi.queryScore(MyThreadLocal.getUserId(), userId);
        TodayBest todayBest = new TodayBest();
        todayBest.setId(userInfo.getUserId());
        todayBest.setAvatar(userInfo.getLogo());
        todayBest.setNickname(userInfo.getNickName());
        todayBest.setGender(userInfo.getSex()== 1 ? "man" : "woman");
        todayBest.setAge(userInfo.getAge());
        todayBest.setTags(StrUtil.splitToArray(userInfo.getTags(),","));
        todayBest.setFateValue(Convert.toLong(recommendUser.getScore()));

        return todayBest;
    }

    public String queryQuestion(Long userId) {
        return "查询问题还没写";
    }

    public void replyQuestion(Long userId, String reply) {
        System.out.println("回答问题还没写");
    }

    public void updateLocation(Double longitude, Double latitude, String address) {
        /*上传用户位置/更新用户位置
         * 第一次上传位置  插入到ES中一条新记录
         * 如果不是第一次  就直接更新他的位置信息*/

        UserLocationVo userLocationVo = userLocationApi.queryByUserId(MyThreadLocal.getUserId());



        if (ObjectUtil.isNull(userLocationVo)) {


            userLocationVo.setUserId(MyThreadLocal.getUserId());
            userLocationVo.setLongitude(longitude);
            userLocationVo.setLatitude(latitude);
            userLocationVo.setAddress(address);
            userLocationVo.setCreated(System.currentTimeMillis());
            userLocationVo.setUpdated(System.currentTimeMillis());
            userLocationVo.setLastUpdated(System.currentTimeMillis());
            userLocationApi.addUserLocation(userLocationVo);
        } else {
            userLocationApi.updateUserLocation(MyThreadLocal.getUserId(), longitude, latitude, address);
        }
    }

    public List<NearUserVo> queryNearUser(String gender, Double distance) {
        //先查询自己的经纬度
        UserLocationVo userLocationVo = userLocationApi.queryByUserId(MyThreadLocal.getUserId());

        //调用api，把自己的位置传送过去，在impl里面用es判断距离
        List<UserLocationVo> userLocationVos = userLocationApi.queryUserFromLocation(userLocationVo.getLongitude(), userLocationVo.getLatitude(), distance, 50);
// 提取附近的人的ID
        List<Long> userIds = CollUtil.getFieldValues(userLocationVos, "userId", Long.class);
        // 查询tb_user_info
        Map<Long, UserInfo> userInfoMap = userInfoApi.findUserInfoByUserid(UserInfo.builder().sex("man".equalsIgnoreCase(gender) ? 1 : 2).build(), userIds);
        // 拼凑VO对象
        List<NearUserVo> nearUserVoList = new ArrayList<>();
        for (UserInfo info : userInfoMap.values()) {
            // 排除自己
            if (info.getUserId().equals(MyThreadLocal.getUserId())) {
                continue;
            }
            NearUserVo nearUserVo = new NearUserVo();
            nearUserVo.setUserId(info.getUserId());
            nearUserVo.setAvatar(info.getLogo());
            nearUserVo.setNickname(info.getNickName());
            nearUserVoList.add(nearUserVo);
        }
        return nearUserVoList;
    }
}
